#include "../../include/public/util.h"
#include <fcntl.h>
#include <sys/vfs.h> 
#include <mntent.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>

// 根据串口号获取设备号
// -1 错误
// 0 非RS485模式
// 1 RS485模式
int util_hw_get_serial_dev(char* model,char* com,char* dev)
{
    char* buf = (char*)util_file_read("./cfg/model_list.json");
    if(buf == NULL)return -1;
    cJSON* root = cJSON_Parse(buf);
    if (root == NULL)
    {
        printf("json parsing model_list null \n");
        const char *error_ptr = cJSON_GetErrorPtr();
        if (error_ptr != NULL)
        {
            printf("Error before: %s\n", error_ptr);
        }
        free(buf);
        return -1;
    }
    cJSON* json_model = cJSON_GetObjectItem(root,model);
    if(json_model == NULL)
    {
        printf("get model:%s null!\n",model);
        free(buf);
        cJSON_Delete(root);
        return -1;
    }

    cJSON* json_serial = cJSON_GetObjectItem(json_model,"serial");
    cJSON* json_dev = cJSON_GetObjectItem(json_serial,com);
    if(json_dev == NULL)
    {
        printf("get %s.serial.%s null!",model,com);
        free(buf);
        cJSON_Delete(root);
        return -1;
    }

    strcpy(dev,json_dev->valuestring);
    free(buf);
    cJSON_Delete(root);

    return 0;
}

void util_hw_ts2tm(char * systime,const time_t * ts)
{
    struct tm * ptm;
    
    ptm = localtime(ts);
    
    /* 系统日期,格式:YYYMMDD */
    sprintf(systime,"%04d-%02d-%02d %02d:%02d:%02d", 
            ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday,
            ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
}

void util_hw_get_systime(char * systime)
{
    time_t seconds;
    struct tm * ptm;
    
    time(&seconds); // 同 nSeconds = time(NULL);
    ptm = localtime(&seconds);
    
    /* 系统日期,格式:YYYMMDD */
    sprintf(systime,"%04d-%02d-%02d %02d:%02d:%02d", 
            ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday,
            ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
}


int util_hw_get_systs(void)
{
    return time(NULL); // 同 nSeconds = time(NULL);
}

int util_hw_set_systime(int ts)
{
    struct timeval tv;
    tv.tv_sec = ts;
    tv.tv_usec = 0;
    settimeofday(&tv,NULL);

    return system("hwclock -w -u");
}

int util_hw_tm2ts(int year,int month,int day,int hour,int min,int sec)
{
    struct tm t;
    t.tm_year = year - 1900;
    t.tm_mon = month - 1;
    t.tm_mday = day;
    t.tm_hour = hour;
    t.tm_min = min;
    t.tm_sec = sec;

    return mktime(&t);
}

static char * skip_token(char *p) 
{ 
    while(isspace(*p)) 
    {
        p++; 
    }
    while(*p && !isspace(*p)) 
    {
        p++; 
    }
    return (char *)p; 
}

static long percentages(int cnt, int *out, int *newdata, int *old, int *diffs) 
{ 
    int i; 
    long change; 
    long total_change; 
    int *dp; 
    long half_total; 

    // initialization 
    total_change = 0; 
    dp = diffs; 

    // calculate changes for each state and the overall change 
    for (i = 0; i < cnt; i++) 
    { 
        if ((change = *newdata - *old) < 0) 
        { 
            // this only happens when the counter wraps 
            change = (int)((unsigned long)*newdata-(unsigned long)*old); 
        } 
        total_change += (*dp++ = change); 
        *old++ = *newdata++; 
    } 

    // avoid divide by zero potential 
    if (total_change == 0) 
    { 
        total_change = 1; 
    } 

    // calculate percentages based on overall change, rounding up 
    half_total = total_change / 2l; 
    half_total = 0; 
    for (i = 0; i < cnt; i++) 
    { 
        *out++ = (int)((*diffs++ * 1000 + half_total) / total_change); 
    } 
    // return the total in case the caller wants to use it 
    return(total_change); 
} 
 

// long dw_clock_cpu_occupy = 0;

//获取CPU占用率
float util_hw_get_cpu_usage(void)
{
    #define NCPUSTATES 5
    static int cp_time[NCPUSTATES]; 
    static int cp_old[NCPUSTATES]; 
    static int cp_diff[NCPUSTATES]; 
    static int cpu_state[NCPUSTATES]; 
    static char buffer[4096+1]; 

    int fd_cpu,len; 
    char *p; 

    //监视CPU占用率
    fd_cpu = open("/proc/stat", O_RDONLY);  ///proc/stat文件用于计算CPU使用率
    len = read(fd_cpu, buffer, sizeof(buffer)-1); 
    close(fd_cpu); 
    buffer[len] = '\0';

    p = skip_token(buffer); //cpu
    cp_time[0] = strtoul(p, &p, 0);     //strtoul()返回长整型数，而且可以返回无符号的长整型数
    cp_time[1] = strtoul(p, &p, 0); 
    cp_time[2] = strtoul(p, &p, 0); 
    cp_time[3] = strtoul(p, &p, 0); 
    cp_time[4] = strtoul(p,&p,0); 

    percentages(NCPUSTATES, cpu_state, cp_time, cp_old, cp_diff); 

    return (float)(cpu_state[0]/10.0);
}    

 